/**
 * ****************************************************************************
 * Project: RoboBridge
 * ----------------------------------------------------------------------------
 * -------------------------- [c]2012 - KrawallMann ---------------------------
 * ---------------------- http://www.krawallmann.de.tc/ -----------------------
 * ****************************************************************************
 * File: ConnectFrame.java Package: tc.de.krawallmann.robobridge.visualization
 * Version: 1.0 Author(s): KrawallMann
 * ****************************************************************************
 * Description:
 * ****************************************************************************
 */
package tc.de.krawallmann.robobridge.visualization;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

import tc.de.krawallmann.robobridge.RoboBridge;
import tc.de.krawallmann.robobridge.communication.AbstractCommunicationInterface;
import tc.de.krawallmann.robobridge.communication.ConnectionListener;
import tc.de.krawallmann.robobridge.communication.DeviceDiscoveryListener;
import tc.de.krawallmann.robobridge.communication.lan.wlan.WLANRemoteDevice;
import tc.de.krawallmann.robobridge.devices.AbstractDevice;


/**
 * The Class ConnectFrame.<br/>
 * Partially auto-generated Javadoc!
 */
public class ConnectFrame extends AbstractRoboViewDisplay implements
		DeviceDiscoveryListener<WLANRemoteDevice>, ConnectionListener<WLANRemoteDevice> {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -6464785787817659563L;

	/** The bridge. */
	private RoboBridge<WLANRemoteDevice> bridge;

	/** The connect. */
	private JButton connect;

	/** The list. */
	private JList<WLANRemoteDevice> list;

	/** The model. */
	private DefaultListModel<WLANRemoteDevice> model;

	/** The state. */
	private JLabel state;

	/**
	 * Instantiates a new connect frame.
	 * 
	 * @param bridge
	 *            the bridge
	 */
	public ConnectFrame(final RoboBridge<WLANRemoteDevice> bridge) {
		super("Connection");
		setClosable(false);
		this.bridge = bridge;
		model = new DefaultListModel<WLANRemoteDevice>();
		bridge.getCommunicationInterface().addConnectionListener(this);
		list = new JList<WLANRemoteDevice>();
		list.setCellRenderer(new ListCellRenderer<WLANRemoteDevice>() {

			protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();

			@Override
			public Component getListCellRendererComponent(
					final JList<? extends WLANRemoteDevice> list, final WLANRemoteDevice value,
					final int index, final boolean isSelected, final boolean cellHasFocus) {
				final JLabel ret =
						(JLabel) defaultRenderer.getListCellRendererComponent(list, value, index,
								isSelected, cellHasFocus);
				ret.setText(value.getName() + ": " + value.getAddress() + ":" + value.getPort());
				return ret;
			}
		});
		list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);

		connect = new JButton("Connect!");
		connect.setEnabled(false);
		state = new JLabel("Scanning...");
		connect.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(final ActionEvent arg0) {
				if (bridge.isConnected()) {
					connect.setEnabled(false);
					connect.setText("Connect!");
					bridge.close(AbstractCommunicationInterface.NORMAL);
					state.setText("Select device and click connect...");
					connect.setEnabled(true);
				} else {
					try {
						if (list.getSelectedIndex() == -1) {
							return;
						}
						connect.setEnabled(false);
						bridge.connect(list.getModel().getElementAt(list.getSelectedIndex()));
						bridge.start();
						connect.setText("Disconnect!");
						state.setText("Connected!");
						connect.setEnabled(true);
					} catch (final IOException e) {
						connect.setText("Connect!");
						e.printStackTrace();
						state.setText("Error... Select device and click connect...");
						connect.setEnabled(true);
					}
				}
			}
		});
		model.addListDataListener(new ListDataListener() {
			@Override
			public void contentsChanged(final ListDataEvent arg0) {
				checkButton();
			}

			@Override
			public void intervalAdded(final ListDataEvent arg0) {
				checkButton();
			}

			@Override
			public void intervalRemoved(final ListDataEvent arg0) {
				checkButton();
			}

			protected void checkButton() {
				if (model.getSize() == 0) {
					connect.setEnabled(false);
					state.setText("Scanning...");
				} else {
					connect.setEnabled(true);
					if (state.getText().equals("Scanning...")) {
						state.setText("Select device and click connect...");
					}
				}
			}
		});
		bridge.getCommunicationInterface().getDeviceScanner().addDeviceDiscoveryListener(this);
		setLayout(new BorderLayout());
		setSize(400, 400);
		final JPanel middlePane = new JPanel();
		middlePane.setOpaque(false);
		middlePane.setLayout(new BorderLayout());
		JLabel chooseLabel = new JLabel("Choose RP6 device:");
		chooseLabel.setForeground(Color.WHITE);
		middlePane.add(BorderLayout.NORTH, chooseLabel);
		middlePane.add(BorderLayout.CENTER, list);
		state.setForeground(Color.WHITE);
		middlePane.add(BorderLayout.SOUTH, state);
		list.setOpaque(false);
		list.setForeground(Color.WHITE);
		add(BorderLayout.CENTER, middlePane);
		add(BorderLayout.SOUTH, connect);
		setVisible(true);
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.robobridge.communication.DeviceDiscoveryListener#
	 * onDeviceDiscovered
	 * (tc.de.krawallmann.robobridge.communication.AbstractRemoteCommunicationDevice
	 * )
	 */
	@Override
	public void onDeviceDiscovered(final WLANRemoteDevice device) {
		model.addElement(device);
		list.setModel(model);
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * tc.de.krawallmann.robobridge.devices.SensorListener#onSensorValueChanged
	 * (tc.de.krawallmann.robobridge.devices.AbstractDevice, java.lang.String,
	 * java.lang.Object, java.lang.Object)
	 */
	@Override
	public void onSensorValueChanged(final AbstractDevice sensor, final String propertyName,
			final Object oldValue, final Object newValue) {

	}

	@Override
	public void onConnect(WLANRemoteDevice device) {

	}

	@Override
	public void onDisconnect(WLANRemoteDevice device, int reason) {
		if(reason==AbstractCommunicationInterface.ERROR){
			state.setText("Error! Select a device and click connect...");
			connect.setText("Connect!");
		}else{
			state.setText("Disconnected. Select a device and click connect...");
			connect.setText("Connect!");
		}
	}

}
